Cloudflare D1 Demo — Cheat Sheet
~5–6 min · One database, two views: the live app and the dashboard · "Italic quotes" = phrases, your words are better · ▶ = action
Before the call
- Cloudflare dashboard logged in · Dustin CF-1 Lab account
- Live demo app open in a browser tab: https://cf-demo-app.dustinburke23nc.workers.dev/
- Second tab open on the D1 Console, already showing the Customers table (see "First time?" below)
- Warm up 5 min before: hit /d1/customers once so the first click in front of the customer is instant
First time? Read this once, then never again.
Two tabs. Two minutes to set up.
1. Open the D1 Console (the SQL editor in the dashboard)
A web based SQL editor built into Cloudflare. Nothing to install.
- Open https://dash.cloudflare.com/ff89748ca36e597848348d987fc25108/workers/d1
- You will see one database in the list. Click demo-d1-database.
- Click the Console tab near the top.
- Type
SELECT * FROM Customers; and click Execute. Five rows appear.
- Leave this tab open. You will switch to it during the demo and paste a bigger query.
2. Open the demo app
Just a URL. Buttons trigger real API calls and the result opens as JSON.
- Open https://cf-demo-app.dustinburke23nc.workers.dev/
- Find the blue D1 — Serverless SQL card. It has two buttons: List Customers and Filter by UK.
That is it. Two tabs, one story, told from both ends.
0. Open (~1 min)
"Every application needs a database. The problem is what comes with one. You provision an instance, you pick a size, you manage connections, you patch it, you pay a monthly minimum whether you use it or not, and you still have to think about where it lives and how far your users are from it. D1 is Cloudflare's take on that. It is a real SQL database, SQLite under the hood, that runs on our network with no server for you to manage and no monthly minimum. Let me show you the same database from two angles. First the application using it, then the dashboard behind it."
1. The app querying D1 (~1.5 min)
▶ Switch to the demo app. On the D1 card, click List Customers. JSON opens in a new tab.
"That button hit a Worker, the Worker ran a SQL query against D1, and you are looking at the result. Five customer rows, real data, real query. There was no connection string to open, no port to expose, no instance sitting idle. The database is just a binding the Worker can call."
What the response looks like:
{
"service": "D1",
"count": 5,
"results": [
{ "CustomerId": 1, "CompanyName": "Alfreds Futterkiste", "ContactName": "Maria Anders", "Country": "Germany" },
{ "CustomerId": 2, "CompanyName": "Around the Horn", "ContactName": "Thomas Hardy", "Country": "UK" },
{ "CustomerId": 3, "CompanyName": "Bs Beverages", "ContactName": "Victoria Ashworth", "Country": "UK" },
{ "CustomerId": 4, "CompanyName": "Cactus Comidas", "ContactName": "Patricio Simpson", "Country": "Argentina" },
{ "CustomerId": 5, "CompanyName": "Eastern Connection", "ContactName": "Ann Devon", "Country": "UK" }
]
}
▶ Click Filter by UK
"Same database, different query. This one runs WHERE Country = 'UK' and returns the three UK customers. Real SQL with real filtering, not a key value store pretending to be a database. Now let me show you where that data actually lives."
Bridge line: "The app is one view. The dashboard is the other. Let me flip to it so you can see this is a managed database, not a file I am faking."
2. The dashboard console (~2 min)
▶ Switch to the D1 Console tab. Run SELECT * FROM Customers;
"This is the same database the app just queried, open in the Cloudflare dashboard. The five rows the app returned are right here. I can run any SQL I want against it directly from the browser, no client to install. The first query just listed the customers. Now let me ask the database a real business question."
"The question is: which of our customers are actually worth the most to us. To answer that I need two tables. One holds the customers. The other holds every order they have ever placed. This next query pulls those two together, counts each customer's orders, adds up what they have spent, and ranks them from most valuable to least. One statement, and the database does all the work."
Paste this, click Execute
SELECT c.CompanyName, c.Country,
COUNT(o.OrderId) AS orders,
SUM(o.Amount) AS lifetime_value
FROM Customers c
LEFT JOIN Orders o ON c.CustomerId = o.CustomerId
GROUP BY c.CustomerId
ORDER BY lifetime_value DESC;
Say this while you paste and click Execute (do not paste in silence):
"Watch what I am doing here. I am taking our list of customers, then for each one I am pulling in every order they have placed. I count those orders, I total up the dollars they have spent, and I sort the whole list so the biggest customers land at the top. I paste it in, I click Execute, and D1 runs all of that in a few milliseconds and hands me the answer."
If they want it line by line (say as much or as little as the room needs):
- SELECT CompanyName, Country → the columns I want to see for each customer.
- COUNT(OrderId) AS orders → count how many orders that customer placed, and label that number "orders".
- SUM(Amount) AS lifetime_value → add up the dollar amount of all their orders, and label that total "lifetime_value".
- FROM Customers → start with the customer list.
- LEFT JOIN Orders ON CustomerId → match each customer to their orders using the shared CustomerId. "Left" just means keep every customer even if they happen to have zero orders, so nobody drops off the report.
- GROUP BY CustomerId → collapse all of one customer's order rows into a single line so the count and sum are per customer, not per order.
- ORDER BY lifetime_value DESC → sort the result with the biggest spenders at the top.
"So in one statement I joined two tables, counted, summed, grouped, and ranked. That is your most valuable customers report, live, straight from the database. Try getting that out of a key value or document store in one line. You would be writing application code to stitch it together by hand."
What comes back:
CompanyName Country orders lifetime_value
------------------- --------- ------ --------------
Eastern Connection UK 3 105
Around the Horn UK 1 65
Cactus Comidas Argentina 1 65
Alfreds Futterkiste Germany 2 30
Bs Beverages UK 2 20
"Read it top down. Eastern Connection is our best customer, three orders, a hundred and five dollars in lifetime value. Bs Beverages is at the bottom with twenty. That is a decision ready answer, not raw rows I still have to add up myself."
"And notice the response time at the bottom of the console, typically a couple of milliseconds. Every write to this database also propagates to read replicas around the world automatically. A user in Sydney reads from a copy near Sydney. You did not set that up, you did not manage a replica, it just happens."
3. The rest of the dashboard (~1.5 min)
▶ Click the Metrics tab
"This is the observability that comes with it. Read queries, write queries, rows read, storage used, all built in. No agent to install, no separate monitoring bill. If you wanted to know whether a query pattern was getting expensive, it is right here."
▶ Open Settings and point out Time Travel
"This is the one that makes DBAs sit up. Time Travel. D1 can restore the database to any point in the last 30 days, down to the minute, with a single command. Someone runs a bad update, someone drops a table, you roll it back. There is no backup job to configure and no snapshot schedule to babysit. It is on by default."
Bridge line: "So that is the whole loop. An app querying it, a console to run SQL, metrics to watch it, and point in time restore to protect it. All of it managed for you."
The Payoff (~1 min)
Why D1 lands
- Real SQL — joins, aggregates, transactions, not a NoSQL substitute
- No server to run — no instance, no patching, no connection pool to size
- Global reads — read replicas placed automatically near your users
- Time Travel — restore to any minute in the last 30 days, on by default
- No monthly minimum — generous free tier, then you pay for what you use
"It is the database you reach for when you do not want to think about running a database. And because it lives on the same platform as your Workers, the app and the data are the same deploy, the same bill, the same dashboard."
Close (~30 sec)
"If you are building something new, or you have a service where the database is more operational overhead than it is worth, D1 is worth a look. And if you already have a Postgres or MySQL you are committed to, we do not make you move it. Hyperdrive accelerates the one you have. Either way you are not stuck."
THE D1 POINT
A real SQL database with no server to run, global reads, and point in time restore built in.
The app and the data on one platform, one bill, one dashboard.
"You get a database. You do not get the job of running one."
If something breaks during the demo
- If the app button is slow, it is a cold Worker. Hit /d1/customers once to warm it, then retry.
- If the Console will not load, the SQL still works from the app buttons. Lead with the app and describe the console.
- Screenshots of the JSON response and the join result saved on the desktop as backup.
- Recovery line: "Perfect time to show you the data model." Point at the Tables view and walk Customers and Orders. A graceful recovery beats a flawless demo.
Quick Answers — back-pocket
Is D1 actually production ready?
Yes. GA since April 2024. Read replicas for low latency global reads, Time Travel for point in time recovery, up to 10GB per database and many databases per account. If you outgrow it, Hyperdrive lets you move to Postgres without rewriting your Worker code.
What is it built on?
SQLite. That means standard SQL, real transactions, and a huge ecosystem of tooling. Cloudflare runs it as a managed service on our network so you never touch the underlying engine.
How big can it get?
10GB per database today, and you can run many databases per account. A common pattern is a database per tenant or per customer, which keeps each one small, fast, and isolated.
How does the global read replication work?
Writes go to a primary and D1 places read replicas around the world automatically. Reads are served from a copy near the user. You do not provision or manage replicas.
What is Time Travel exactly?
Point in time restore. D1 keeps a rolling 30 day history and can restore the whole database to any minute in that window with one command. No backup jobs to schedule. It is on by default.
What does it cost?
Generous free tier: 5GB storage and millions of rows read per day at no cost. Beyond that you pay for rows read, rows written, and storage. No instance to keep running means no monthly minimum for an idle database.
We already have Postgres in AWS. Why would we move?
You do not have to. D1 is for new work or for services where running a database is more trouble than it is worth. For the Postgres you are committed to, Hyperdrive pools and caches it at our edge so it gets faster without a migration.
Can I see the code?
Yes. The whole endpoint is a few lines: env.DB.prepare("SELECT * FROM Customers").all(). The database is one binding in wrangler.jsonc. Happy to share the repo.